package com.asset.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.asset.common.ErrorCode;
import com.asset.constant.UserConstant;
import com.asset.exception.BusinessException;
import com.asset.mapper.CompanyMapper;
import com.asset.mapper.UserMapper;
import com.asset.model.entity.Company;
import com.asset.model.entity.User;
import com.asset.model.vo.LoginUserVO;
import com.asset.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import javax.annotation.Resource;

@Service
@Slf4j
public class UserServiceImpl implements UserService {

    @Resource
    private UserMapper userMapper;
    
    @Resource
    private CompanyMapper companyMapper;

    /**
     * @param username 账号
     * @param password 密码
     * @return
     */
    @Override
    public LoginUserVO userLogin(String username, String password) {
        // 校验参数
        if (StrUtil.hasBlank(username, password)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空");
        }
        // 用户账号不能少于 4 位
        if (username.length() < 4) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户账号错误");
        }
        // 用户密码不能小于 8 位
        if (password.length() < 8) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户密码错误");
        }
        // 对用户密码进行加密, 暂时不用
        //String encryptPassword = getEncryptPassword(password);
        // 查询数据库中的用户是否存在
        User user = userMapper.selectOneUser(username, password);
        // 用户不存在, 返回错误
        if (user == null) {
            log.info("用户不存在");
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户名或者密码错误");
        }
        LoginUserVO loginUserVO = getLoginUserVO(user);
        // 使用 sa-token 更好, 设置登录态
        int userId = user.getId();
        StpUtil.login(userId);
        // 将登录者信息存入 sa-token
        StpUtil.getSession().set(UserConstant.USER_LOGIN_STATE, loginUserVO);
        // 可以将会话信息存入Redis（如果需要分布式存储）
//        SaSession session = StpUtil.getSession();
//        session.set("userInfo", user);
        // 获取 token 并将token 保存在 loginUserVO 中
        loginUserVO.setToken(StpUtil.getTokenInfo().getTokenValue());
        // 根据 用户所属公司id 拿到公司名称和公司编码
        int companyId = user.getCompanyId();
        Company company =  companyMapper.getCompanyById(companyId);
        loginUserVO.setCompanyName(company.getName());
        loginUserVO.setCompanyCode(company.getCompanyCode());
        return loginUserVO;
    }

    @Override
    public LoginUserVO getLoginUserVOByTK() {
        // 从 sa-token 中获取登录者信息
        LoginUserVO loginUser = (LoginUserVO) StpUtil.getSession().get(UserConstant.USER_LOGIN_STATE);
        
        if (loginUser == null) {
            throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR);
        }
        return loginUser;
    }


    /**
     * 获取脱敏后登录用户信息
     *
     * @param user 用户对象
     * @return 脱敏后的登录用户信息
     */
    private LoginUserVO getLoginUserVO(User user) {
        if (user == null) {
            return null;
        }
        LoginUserVO loginUserVo = new LoginUserVO();
        BeanUtil.copyProperties(user, loginUserVo);
        return loginUserVo;
    }

    /**
     * 获取加密后的密码
     *
     * @param password 密码
     * @return 加密后的密码
     */
    private String getEncryptPassword(String password) {
        // 加盐, 混淆密码
        final String SALT = "asset";
        return DigestUtils.md5DigestAsHex((SALT + password).getBytes());
    }


//    /**
//     * 获取脱敏类的用户信息
//     *
//     * @param user 用户
//     * @return 脱敏后的用户信息
//     */
//    @Override
//    public LoginUserVO getLoginUserVO(User user) {
//        if (user == null) {
//            return null;
//        }
//        LoginUserVO loginUserVO = new LoginUserVO();
//        BeanUtil.copyProperties(user, loginUserVO);
//        return loginUserVO;
//    }


    /**
     * 退出登录
     *
     * @return 是否退出成功
     */
    @Override
    public boolean userLogout() {
        // 使用 sa-token
        // 清除 session
        StpUtil.getSession().logout();
        // 退出登录
        StpUtil.logout();
        return true;
    }


}
